using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
using MAPI;
using Microsoft.Win32;
using SharePoint.ImportExport.Core;
using Exchange.Export.MHTMLHelper;
namespace Exchange.Export.DataHandler
{
	/// <summary>
	/// Summary description for helperFunctions.
	/// </summary>
	public class helperFunctions
	{
		[DllImport("MAPIWrapper.dll",EntryPoint="#8",  SetLastError=true,		CharSet=CharSet.Unicode, ExactSpelling=true,		CallingConvention=CallingConvention.StdCall)]
		unsafe public static extern int fnCreateRTWindow();

		[DllImport("MAPIWrapper.dll",EntryPoint="#9",  SetLastError=true,		CharSet=CharSet.Unicode, ExactSpelling=true,		CallingConvention=CallingConvention.StdCall)]
		unsafe public static extern int fnDeleteRTWindow(int hWnd);

		
		[DllImport("MAPIWrapper.dll",EntryPoint="#3",  SetLastError=true,		CharSet=CharSet.Unicode, ExactSpelling=true,		CallingConvention=CallingConvention.StdCall)]
		unsafe public static extern int fnExportMailMessage([MarshalAs(UnmanagedType.IUnknown)] Object obj, [MarshalAs(UnmanagedType.LPStr)] String szPath, int type, int hwnd, [MarshalAs(UnmanagedType.LPStr)] String szDirName, ref int ExportedAs);

		public helperFunctions()
		{
			//
			// TODO: Add constructor logic here
			//
		}
		public string insertMessage(MAPI.Message oMessage, int type, string sName, string folder, int hWnd, string tempDir)
		{
			int retValue=-1;
			string fileNameAndPath="";
			string tempName = sName;
			fileNameAndPath=sName.Replace("..","_");
			int pos=fileNameAndPath.IndexOf("..");
			while(pos>=0)
				fileNameAndPath=fileNameAndPath.Replace("..","_");
			switch(type)
			{
				case Constants.MSGFILE:
					tempName=tempName+".msg";
					break;
				case Constants.TXTFILE:
					tempName=tempName+".txt";
					break;

			}
			bool fileFound=true;
			int fIndex=0;
			while(fileFound)
			{
				if((File.Exists(folder + "\\" + tempName+".rtf")||(File.Exists(folder + "\\" + tempName+".mhtml"))))
				{
					fIndex++;
					tempName=sName+"-"+fIndex.ToString();
				}
				else
					fileFound=false;
				
			}
			fileNameAndPath = folder + "\\" + tempName;
			int exportedType=1;
			retValue = fnExportMailMessage(oMessage.MAPIOBJECT,fileNameAndPath,type, hWnd,tempDir,ref exportedType);
			if (retValue==-6)
			{
				Logger.Log(ErrorLevel.File,"Warning, The extractor detected an OLE object that it couldn't serialize in message \""+oMessage.Subject.ToString()+"\". Possible reason might be that the application for using that object is not installed on the extractor machine");
				retValue=0;
			}

			if (retValue!=0)
			{
				fileNameAndPath = fileNameAndPath + ".rtf";
				retValue = fnExportMailMessage(oMessage.MAPIOBJECT,fileNameAndPath,Constants.RTFFILE, hWnd,tempDir, ref exportedType);
				if(!sName.EndsWith(".rtf"))
					sName=sName+".rtf";

			}
			if (retValue==0)
			{
				if(exportedType==Constants.HTMLFILE)
				{
					MHTMLHelper.ExtractMailAsMHTML  mhtmCreator=new MHTMLHelper.ExtractMailAsMHTML();
					if(fIndex>0)
						mhtmCreator.FileName=sName+"-"+fIndex.ToString();
					else
						mhtmCreator.FileName=sName;
					mhtmCreator.FolderName=tempDir;
					mhtmCreator.DestFolderName=folder;
					if(mhtmCreator.Save())
						sName=mhtmCreator.DestFileName;
				}
				else if(exportedType==Constants.RTFFILE)
				{
					if(!sName.EndsWith(".rtf"))
						sName=sName+".rtf";

				}
                else if (exportedType == Constants.MSGFILE)
                {
                    if (!sName.EndsWith(".msg"))
                        sName = sName + ".msg";

                }
            }
			return(sName);
		}
		public bool writeToFile(string fileNameAndPath, string body)
		{
			try
			{
				StreamWriter writer = new StreamWriter(fileNameAndPath);
				writer.Write(body);
				writer.Close();
				return(true);
			}
			catch (Exception ex)
			{
				Console.WriteLine (ex.Message);
				return (false);
			}
		}
		public string getGUID()
		{
			string temp = System.Guid.NewGuid().ToString();
			return (temp);
		}
		public string createFolder (string path)
		{
			
			//			if (path.Length == 0)
			//			{	
			//				ArrayList al = getConfigValues("//configuration/folders/createStructureFolder");
			//				foreach (object item in al)
			//				{
			//					path = item.ToString();	
			//				}
			//			}
			string delimStr = @"\";
			char [] delimiter = delimStr.ToCharArray();
			string [] temp = path.Split(delimiter);
			string tempFolderName = "";
			
			foreach (string s in temp) 
			{
				if (s.EndsWith(":")== true)
				{
					tempFolderName += s + @"\";
					
				}
				else
				{
					if (tempFolderName.EndsWith(delimStr))
					{
						tempFolderName += s;
					}
					else
					{
						tempFolderName += @"\" + s;
					}
					if (Directory.Exists(tempFolderName)!= true)
					{
						Directory.CreateDirectory(tempFolderName);
					}
					Directory.SetCurrentDirectory(tempFolderName);
				}
			
			}
			//Console.Write(tempFolderName);
			return (tempFolderName);
		}
		//		public ArrayList getConfigValues (string nodeName)
		//		{
		//			string appPath = Application.StartupPath.ToString();
		//			ArrayList temp = new ArrayList();
		//			XmlDocument doc = new XmlDocument();
		//			doc.Load(appPath + @"\config.xml");
		//			//XmlNodeList nodeList = doc.SelectNodes("//configuration/extensions/extension");
		//			XmlNodeList nodeList = doc.SelectNodes(nodeName);
		//			foreach (XmlNode nd in nodeList)
		//				temp.Add ((object)nd.InnerText);
		//			return (temp);
		//		}
		//gets in ie. 
		//startPath c:\inetpub\wwwroot
		//Path c:\inetpub\wwwroot\dir\SubDirectory
		//Returns string dir\SubDirectory
		public string getRelativePath(string startPath, string Path)
		{
			string delimStr = @"\";
			char [] delimiter = delimStr.ToCharArray();
			string [] tempStartPath = startPath.Split(delimiter);
			string [] tempPath = Path.Split(delimiter);
			int seed=0; 
			string tempString;
			string retString="";
			int tem=0;

			foreach (string s in tempPath) 
			{
				tem = tempStartPath.Length;
				if (tempStartPath.Length > seed) 
				{
					tempString = tempStartPath[seed];
					if (s != tempStartPath[seed])
					{
						if (retString.Trim()=="")
						{
							retString = s;
						}
						else 
						{
							retString += @"\" + s;
						}
					}
				}
				else
				{
					if (retString.Trim()=="")
					{
						retString = s;
					}
					else 
					{
						retString += @"\" + s;
					}
				}
				seed += 1;
			}
			return (retString);
		}
		
		public unsafe static string GetDomainAccountFromAddressEntry(MAPI.AddressEntry addrEntry)
		{
			string domainAccount="";
			try
			{
				object vEmpty = Missing.Value;
				uint id=2150039810;
				
				MAPI.Fields oAddrfields=(MAPI.Fields)addrEntry.Fields;
				FieldsHelper oAddressFieldsHelper= new FieldsHelper(oAddrfields);
				MAPI.Field oSenderField=oAddressFieldsHelper.GetField(id,vEmpty);
				string ssid=oSenderField.Value.ToString();
				//The SID is stored in a hexadecimal representation of the binary SID so we convert it and store it in a byte array
				byte[] bsid=new byte[ssid.Length/2];
				for(int i=0;i<ssid.Length/2;i++)
				{
					bsid[i]=System.Convert.ToByte(ssid.Substring(i*2,2),16);
				}
				fixed(byte *psid = bsid)

				{
		
					IntPtr psidPtr = (IntPtr)psid;
					Microsoft.Win32.Security.Sid msid=new Microsoft.Win32.Security.Sid(psidPtr);
					domainAccount=msid.DomainName+"\\"+msid.AccountName;
				}
 
				return domainAccount;
			}
			catch
			{
			}
			return "";
			//LookupAccountSid(null,


		}
		private unsafe static string GetACLEntryName(MAPI.Session mapiSession,object ACLEntryID, out string userName, out string userEmail)
		{
			// This function finds the user that is listed as an ACE on the folder.
			//It takes the ID that it is passed and uses the Session.GetAddressEntry method
			// to find the name.
			userName="";
			userEmail="";
			const int PR_SMTP_ADDRESS = 0x39fe001f;
			
			if(ACLEntryID.ToString() == "ID_ACL_DEFAULT")
			{
				// The default ACE
				return "everyone"; //
			}
			else if(ACLEntryID.ToString() == "ID_ACL_ANONYMOUS")
			{
				// The default ACE
				return "Anonymous";
			}
			else
			{

				uint id=2150039810;
				// Get the name of the ACE
				MAPI.AddressEntry addressEntry=(MAPI.AddressEntry)mapiSession.GetAddressEntry(ACLEntryID);
				
				MAPI.Fields oAddrfields=(MAPI.Fields)addressEntry.Fields;
				object vEmpty = Missing.Value;
				MAPI.Field field=(MAPI.Field)oAddrfields.get_Item(MAPI.CdoPropTags.CdoPR_DISPLAY_NAME,vEmpty);
				userName=field.Value.ToString();
				field=(MAPI.Field)oAddrfields.get_Item(MAPI.CdoPropTags.CdoPR_ADDRTYPE,vEmpty);
				if(field.Value.ToString()=="EX")
					field=(MAPI.Field)oAddrfields.get_Item(PR_SMTP_ADDRESS,vEmpty);
				else
					field=(MAPI.Field)oAddrfields.get_Item(MAPI.CdoPropTags.CdoPR_EMAIL_ADDRESS,vEmpty);
				userEmail=field.Value.ToString();
				
				MAPI.Field oSenderField=(MAPI.Field)oAddrfields.get_Item(id,vEmpty);
				string ssid=oSenderField.Value.ToString();
				//The SID is stored in a hexadecimal representation of the binary SID so we convert it and store it in a byte array
				byte[] bsid=new byte[ssid.Length/2];
				for(int i=0;i<ssid.Length/2;i++)
				{
					bsid[i]=System.Convert.ToByte(ssid.Substring(i*2,2),16);
				}
				fixed(byte *psid = bsid)
				{
					IntPtr psidPtr = (IntPtr)psid;
					Microsoft.Win32.Security.Sid msid=new Microsoft.Win32.Security.Sid(psidPtr);
					return msid.DomainName+"\\"+msid.AccountName;
				}
 
			}
		}
		private static string ReturnACE(object ofolderACE)
		{
			string retValue="None";
			ACLWrapper.IACE folderACE=(ACLWrapper.IACE)ofolderACE;
			ACLWrapper.ACLRIGHTS acl=(ACLWrapper.ACLRIGHTS)folderACE.Rights ;
	
			if((acl& ACLWrapper.ACLRIGHTS.RIGHTS_FOLDER_OWNER) == ACLWrapper.ACLRIGHTS.RIGHTS_FOLDER_OWNER)
			{
				return "administrator";
			}
			if((acl& ACLWrapper.ACLRIGHTS.ROLE_EDITOR) == ACLWrapper.ACLRIGHTS.ROLE_EDITOR)
			{
				return "contributor";
			}
			if((acl& ACLWrapper.ACLRIGHTS.ROLE_REVIEWER) == ACLWrapper.ACLRIGHTS.ROLE_REVIEWER)
			{
				return "reader";
			}
			return retValue;
		}

		public static bool  ReadSecurityFromFolder(MAPI.Folder folder, Site container, MAPI.Session session)
		{
			try
			{
				ACLWrapper.ACLObjectClass folderACL=new ACLWrapper.ACLObjectClass();
				folderACL.CDOItem=folder;
				ACLWrapper.IACEs folderACEs=(ACLWrapper.IACEs)folderACL.ACEs;
				int ACECount=folderACEs.Count;
				for(int j=1;j<=ACECount;j++)
				{
					string role="";
					string account="";
					string userName="";
					string userEmail="";
					ACLWrapper.ACE folderACE=(ACLWrapper.ACE) folderACEs.Item(j);
					account=GetACLEntryName(session,folderACE.ID,out userName, out userEmail);
					role=ReturnACE(folderACE);
					if("None"!=role)
					{
						User user = new User();
						user.Role=role;
						user.Account=account;
						user.Name=userName;
						user.Email=userEmail;
						container.UserInfo.Users.Add(user);
					}
				}
			}
			catch
			{
				return false;
			}
			return true;


		}

	
	}
}

